import {isObject, isString} from '@/utils/toolFun'
import qs from 'qs'


// 初始化选项 baseUrl配置， 拦截器。
// 设置baseUrl
const baseURL = process.env.VUE_APP_BASE_API
const initialConfig = {
    method: "GET",
    params: null,// get系列请求使用
    body: null,// post系列请求使用 get系列请求不可传body，报错
    headers: {
        "content-type": "application/json"
    }, // 请求头信息
    catch: "no-cache",// 请求不缓存
    // credentials: "include", // 跨域携带信息 cookie等
    responseType: "json", // 响应的数据格式
}
const httpApi = (val) => {
    let {url, config, paramsType, data, isReturnAll = false} = val
    // 判断url是否是字符串
    if (typeof url !== 'string') {
        throw new TypeError("url must be required and of string type!")
    }
    // 合并传入的配置项和初始化配置项
    config = Object.assign({}, initialConfig, config)
    if (/^http(s?):\/\//i.test(url)) url = baseURL + url;
    // let { method, params, body, headers, cache, credentials, responseType } = config;
    let { responseType } = config;
    // 对请求体body进行处理
    // 根据参数判断请求携带参数的格式 有formadata表单格式，serach拼接在url后面的模式，默认为json格式。
    switch (paramsType) {
        case 'formdata':
            break;
        case 'search':
            url += '?' + qs.stringify(data)
            break;
        default:
            if (isObject(data)) { // 将js对象转化为json对象
                // body = JSON.stringify(body) // 这里不会修改config.body的值。多层嵌套是不可以的。
                config.body = JSON.stringify(data)
            } else if (isString(data)) {
                // 这里不清楚呢
                config.body = JSON.stringify(JSON.parse(data))
            }
            break;
    }
    return fetch(baseURL + url, config).then((response) => {
        let { status, statusText } = response;
        if (status >= 200 && status < 400) {
            let result;
            switch (responseType.toUpperCase()) {
                case "JSON":
                    result = response.json();
                    break;
                case "TEXT":
                    result = response.text();
                    break;
                case "BLOB":
                    result = response.blob();
                    break;
                case "ARRAYBUFFER":
                    result = response.arrayBuffer();
                    break;
                default: // 都不匹配 转json
                    result = response.json();
                    break;
            }
            return result
        }
        return Promise.reject({
            code: "STATUS ERROR",
            status,
            statusText
        })
    }).then((result) => {
        // 对成功结果进行处理
        switch (result.resultCode) {
            case 400:
                alertError(result.errorMsg || result.error)
                break;
            case 401:
                alertError(result.errorMsg || result.error)
                break;
            case 402:
                alertError(result.errorMsg || result.error)
                break;
            case 403:
                alertError(result.errorMsg || result.error)
                break;
            case 404:
                alertError(result.errorMsg || result.error)
                break;
            case 500:
                alertError(result.errorMsg || result.error)
                break;
            default:
                break;
        }
        if (isReturnAll) return result;
        return result.result
    }).catch(reason => {
        // 失败情况
        // @1. 状态码错误
        if (reason && reason.code === "STATUS ERROR") {
            switch (reason.resultCode) {
                case 400:
                    alertError(reason.errorMsg || reason.error)
                    break;
                case 401:
                    alertError(reason.errorMsg || reason.error)
                    break;
                case 402:
                    alertError(reason.errorMsg || reason.error)
                    break;
                case 403:
                    alertError(reason.errorMsg || reason.error)
                    break;
                case 404:
                    alertError(reason.errorMsg || reason.error)
                    break;
                case 500:
                    alertError(reason.errorMsg || reason.error)
                    break;
                default:
                    break;
            }
        }
        // @2. 网络中断
        else if (!navigator.onLine) { }
        // @3 其他错误 如请求被终止 取消等
        else { }
        return Promise.reject(reason);
    })
};

function alertError(content) {
    message.warning({ content: content, className: "custom-error-class" })
}
export default httpApi